﻿using InCom.Parts;
using Microsoft.CSharp;
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

namespace Demo
{
    class Program
    {

        public class abc { public byte[] a { get; set; } public string[] c { get; set; } }
        static void Main(string[] args)
        {

            var jsonstr = Json.ToJsonString(new abc { a = new byte[] { 1, 2, 3, 4, 5, 67, 8, 9 },c=new string[]{"a","b","c"} });
            var bytes = Json.ToObject<abc>(jsonstr);

            Console.WriteLine(Json.ToJsonString(new object[] { null }));
            //Test1(true);
            //Test2();
            var str = "{ Name : \"blqw\", Age : 11 ,Array : [\"2014-1-1 1:00:00\",false,{ a:1,b:2 }] }";
            dynamic json = Json.ToDynamic(str);
            Console.WriteLine(json.Name);
            Console.WriteLine(json.Age);
            Console.WriteLine(((DateTime)json.Array[0]).ToShortDateString());
            Console.WriteLine(((bool)json.Array[1]) == false);
            Console.WriteLine(json.Array[2].a);
            Console.WriteLine(json.Array[2].b);


            Test3();

            Console.Read();

        }

        static void Test1(bool fastjson)
        {
            var obj1 = User.TestUser();
            var obj2 = InCom.Parts.Json.ToObject<ResultDTO>(File.ReadAllText("json1.txt"));
            var obj3 = InCom.Parts.Json.ToObject<List<Object2>>(File.ReadAllText("json2.txt"));

            TimeTest.TestCount = 100000 * 5;
            TimeTest.TestObject = obj1;
            TimeTest.TestQuickJsonBuilder();
            if (fastjson) TimeTest.TestFastJson();

            Console.WriteLine("========================");
            TimeTest.TestCount = 2000 * 5;
            TimeTest.TestObject = obj2;
            TimeTest.TestQuickJsonBuilder();
            if (fastjson) TimeTest.TestFastJson();

            Console.WriteLine("========================"); ;
            TimeTest.TestCount = 250 * 5;
            TimeTest.TestObject = obj3;
            TimeTest.TestQuickJsonBuilder();
            if (fastjson) TimeTest.TestFastJson();

            //var obj2 = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultDTO>(jsonStr);
            //var jsonStr1 = InCom.Parts.Json.ToJsonString(obj1);

            //Class1.AssertEquals(obj1, obj2);
        }

        static void Test2()
        {
            //var json1 = InCom.Parts.Json.ToJsonString(User.TestUser());
            var json2 = File.ReadAllText("json1.txt");
            var json3 = File.ReadAllText("json2.txt");

            //TimeTest.TestCount = 1000;
            //TimeTest.TestJsonString = json1;
            //TimeTest.TestQuickJsonBuilder<User>();
            //TimeTest.TestFastJson<User>();

            //Console.WriteLine("========================");
            //TimeTest.TestCount = 200;
            //TimeTest.TestJsonString = json2;
            //TimeTest.TestQuickJsonBuilder<ResultDTO>();
            //TimeTest.TestFastJson<ResultDTO>();

            Console.WriteLine("========================"); ;
            TimeTest.TestCount = 25;
            TimeTest.TestJsonString = json3;
            TimeTest.TestQuickJsonBuilder<List<Object2>>();
            TimeTest.TestFastJson<List<Object2>>();

            //var obj2 = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultDTO>(jsonStr);
            //var jsonStr1 = InCom.Parts.Json.ToJsonString(obj1);

            //Class1.AssertEquals(obj1, obj2);
        }

        /// <summary>
        /// 代码段生成
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="options"></param>
        static CodeSnippetTypeMember GenCodeFromMember(CodeDomProvider provider, CodeGeneratorOptions options)
        {
            options.BracingStyle = "C";
            CodeMemberMethod method1 = new CodeMemberMethod();
            method1.Name = "ReturnString";
            method1.Attributes = MemberAttributes.Public;
            method1.ReturnType = new CodeTypeReference("System.String");
            method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "text"));
            method1.Statements.Add(new CodeMethodReturnStatement(new CodeArgumentReferenceExpression("text")));
            StringWriter sw = new StringWriter();
            provider.GenerateCodeFromMember(method1, sw, options);
            var snippetMethod = new CodeSnippetTypeMember(sw.ToString());

            return snippetMethod;
        }


        static void Test3()
        {
            var provider = CodeDomProvider.CreateProvider("cs");
            // Create a code snippet to be used in the graph.
            GenCodeFromMember(provider, new CodeGeneratorOptions());


            var dd = typeof(ABCcs);
            var 获取引用的程序集合 = dd.Module.Assembly.GetReferencedAssemblies();
            //是否从全局应用程序缓存加载
            //dd.Module.Assembly.GlobalAssemblyCache;

            var resl= from an in 获取引用的程序集合
                      let ass=  System.Reflection.Assembly.Load(an)
                      select (ass.GlobalAssemblyCache? an.Name + ".dll"
                          //引用外部dll "C:\mydll.dll"
                      :  "\""+ass.Location +"\"");
                      ;

            CSharpExe codrun = new CSharpExe();
            string code = @"   
namespace Codes{
public class TTTest {
       public string NewJosn(object a) {
           return Newtonsoft.Json.JsonConvert.SerializeObject(a);
       }
   }
}";
        

            codrun.CompilerCparmae.ReferencedAssemblies.Clear();
            //引用外部dll /reference:"C:\mydll.dll"
            codrun.CompilerCparmae.ReferencedAssemblies.AddRange(resl.ToArray());


            System.Reflection.Assembly dyAss = null;

            ///动态生成程序集合
            System.Linq.Enumerable.Range(1, 100).ToList().ForEach((o) => {
 
                    var ddd = codrun.RunCode(code);
                    var sb  = ddd;
                    dyAss = ddd.CompiledAssembly;
            });
   


            int a = 1, b = 2;
            ABCcs cs = new ABCcs();
            CodeTimer.Time("Dyfirst", 1, () => { cs.d(b); });
            CodeTimer.Time("dycycl", 10000 * 10000, () => { cs.d(b); });
            CodeTimer.Time("uxbox", 10000 * 10000, () => { cs.dx(b); });
            CodeTimer.Time("ucode", 10000 * 10000, () => { var s = a + b; });

            a = a + b;

            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                try
                {
                    Console.WriteLine((a = a + b));
                }
                catch
                {
                }
                System.Threading.Thread.Sleep(1000);
            })
                                            .ContinueWith((t) =>
                                            {
                                                try
                                                {
                                                    throw new Exception("?出错");
                                                    Console.WriteLine((a = a + b));
                                                }
                                                catch (Exception ex)
                                                {
                                                    Console.WriteLine((a = a + b) + ex.ToString());
                                                }
                                            })
                                            .ContinueWith((t) =>
                                            {
                                                try
                                                {
                                                    Console.WriteLine((a = a + b) + "结束...");
                                                }
                                                catch
                                                {
                                                }
                                            })
                                                 ;

        }



    }


    public class ResultDTO
    {
        public bool Result { get; set; }
        public string Message { get; set; }
        public DTOItem[] data { get; set; }
        public int total { get; set; }

        public class DTOItem
        {
            public long vptNum { get; set; }
            public int state { get; set; }
            public DateTime tdate { get; set; }
            public string ntype { get; set; }
            public int abnormal { get; set; }
        }
    }


    public class Object2
    {
        public string ORGCODE { get; set; }
    }



    /// <summary>
    ///C#代碼動態編譯器
    ///請使用實例化後訪問
    /// </summary>
    public class CSharpExe
    {

        public CSharpExe()
        {
            MyCparmae.GenerateInMemory = true;
            MyCparmae.GenerateExecutable = false;
            MyCparmae.IncludeDebugInformation = true;
            //MyCparmae.CompilerOptions = "/target:library";//create type Libray

            MyCparmae.ReferencedAssemblies.Add("System.dll");
            MyCparmae.ReferencedAssemblies.Add("System.Web.dll");
            MyCparmae.ReferencedAssemblies.Add("System.Data.dll");
            MyCparmae.ReferencedAssemblies.Add("System.Xml.dll");

 

        }

        /// <summary>
        /// 新建的编译器类型
        /// </summary>
        Microsoft.CSharp.CSharpCodeProvider MyCSharp = new CSharpCodeProvider();

        /// <summary>
        /// 实例化新的编写的参数
        /// </summary>
        private System.CodeDom.Compiler.CompilerParameters MyCparmae = new System.CodeDom.Compiler.CompilerParameters();


        /// <summary>
        /// 默认编译参数
        /// </summary>
        public System.CodeDom.Compiler.CompilerParameters CompilerCparmae
        {
            get { return MyCparmae; }
        }

        /// <summary>
        /// 動態編譯
        /// </summary>
        /// <param name="Code">執行的代碼</param>
        /// <param name="compilerParameters">編譯的參數</param>
        /// <returns>返回編譯後的程集</returns>
        public System.CodeDom.Compiler.CompilerResults RunCode(string[] codes, System.CodeDom.Compiler.CompilerParameters compilerParameters = null)
        {
            if (compilerParameters == null)
            {
                compilerParameters = MyCparmae;
            }


            return MyCSharp.CompileAssemblyFromSource(compilerParameters, codes);
        }

        /// <summary>
        /// 動態編譯
        /// </summary>
        /// <param name="code">執行的代碼</param>
        /// <param name="compilerParameters">編譯的參數</param>
        /// <returns>返回編譯後的程集</returns>
        public System.CodeDom.Compiler.CompilerResults RunCode(string code, System.CodeDom.Compiler.CompilerParameters compilerParameters = null)
        {
            return RunCode(new string[] { code }, compilerParameters); 
        }

    }
}
